package com.jindy.module.oaLeaveApproval.service.impl;

import com.jindy.activiti.domain.BizExampleDemo;
import com.jindy.activiti.service.IProcessService;
import com.jindy.common.constant.Constants;
import com.jindy.common.exception.base.BaseException;
import com.jindy.common.utils.DateUtils;
import com.jindy.common.utils.SecurityUtils;
import com.jindy.common.utils.StringUtils;
import com.jindy.jpush.utils.UniJpushUtils;
import com.jindy.module.approvalRecord.domain.ApprovalRecord;
import com.jindy.module.approvalRecord.mapper.ApprovalRecordMapper;
import com.jindy.module.jpush.mapper.JpushMapper;
import com.jindy.module.oaLeaveApproval.domain.SyOaLeaveApproval;
import com.jindy.module.oaLeaveApproval.mapper.SyOaLeaveApprovalMapper;
import com.jindy.module.oaLeaveApproval.service.ISyOaLeaveApprovalService;
import com.jindy.module.oacopy.service.ISyOaCopyService;
import com.jindy.module.oacopyconfig.domain.SyOaCopyConfig;
import com.jindy.module.oacopyconfig.mapper.SyOaCopyConfigMapper;
import com.jindy.module.serialNum.service.ISySerialNumTService;
import com.jindy.module.syTableRecord.service.ISyTableRecordTService;
import com.jindy.system.domain.SysUserRoleDeptInfo;
import com.jindy.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 请假审批Service业务层处理
 * 
 * @author jindy
 * @date 2023-05-16
 */
@Service
public class SyOaLeaveApprovalServiceImpl implements ISyOaLeaveApprovalService 
{
    private static final Logger LOGGER = LoggerFactory.getLogger(SyOaLeaveApprovalServiceImpl.class);
    @Autowired
    private SyOaLeaveApprovalMapper syOaLeaveApprovalMapper;

    /**
     * 审批流
     */
    @Autowired
    private IProcessService processService;

    /**
     * 抄送Service
     */
    @Resource
    private ISyOaCopyService syOaCopyService;

    /**
     * 用户Service
     */
    @Resource
    private ISysUserService sysUserService;

    /**
     * 配置表
     */
    @Resource
    private SyOaCopyConfigMapper syOaCopyConfigMapper;

    /**
     * 生成流水单号Service
     */
    @Resource
    private ISySerialNumTService serialNumTService;

    /**
     * 审批记录Service
     */
    @Resource
    private ApprovalRecordMapper approvalRecordMapper;

    /**
     * 设备Mapper
     */
    @Resource
    private JpushMapper jpushMapper;

    /**
     * 存储表Service
     */
    @Resource
    private ISyTableRecordTService iSyTableRecordTService;

    /**
     * 查询请假审批
     * 
     * @param id 请假审批主键
     * @return 请假审批
     */
    @Override
    public SyOaLeaveApproval selectSyOaLeaveApprovalById(Long id)
    {
        return syOaLeaveApprovalMapper.selectSyOaLeaveApprovalById(id);
    }

    /**
     * 查询请假审批列表
     * 
     * @param syOaLeaveApproval 请假审批
     * @return 请假审批
     */
    @Override
    public List<SyOaLeaveApproval> selectSyOaLeaveApprovalList(SyOaLeaveApproval syOaLeaveApproval)
    {
        if (!SecurityUtils.isAdmin(SecurityUtils.getLoginUser().getUser().getUserId())) {
            syOaLeaveApproval.setCreateBy(SecurityUtils.getUsername());
        }
        List<SyOaLeaveApproval> list = syOaLeaveApprovalMapper.selectSyOaLeaveApprovalList(syOaLeaveApproval);
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(item -> {
                try {
                    processService.richProcessField(item);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        return list;
    }

    /**
     * 新增请假审批
     * 
     * @param syOaLeaveApproval 请假审批
     * @return 结果
     */
    @Override
    public int insertSyOaLeaveApproval(SyOaLeaveApproval syOaLeaveApproval)
    {
        // 生成流水单号
        String serialNum = serialNumTService.generateSerialNum("QJSP");
        if (StringUtils.isBlank(serialNum)) {
            throw new BaseException("新增请假审批-获取外出单号失败");
        }
        syOaLeaveApproval.setSerialNum(serialNum);
        syOaLeaveApproval.setBusinessStatus(Constants.DRAFT);
        syOaLeaveApproval.setCreateTime(DateUtils.getNowDate());
        iSyTableRecordTService.saveEntityAndTable(syOaLeaveApproval,serialNum);
        return syOaLeaveApprovalMapper.insertSyOaLeaveApproval(syOaLeaveApproval);
    }

    /**
     * 修改请假审批
     * 
     * @param syOaLeaveApproval 请假审批
     * @return 结果
     */
    @Override
    public int updateSyOaLeaveApproval(SyOaLeaveApproval syOaLeaveApproval)
    {
        syOaLeaveApproval.setUpdateTime(DateUtils.getNowDate());
        return syOaLeaveApprovalMapper.updateSyOaLeaveApproval(syOaLeaveApproval);
    }

    /**
     * 批量删除请假审批
     * 
     * @param ids 需要删除的请假审批主键
     * @return 结果
     */
    @Override
    public int deleteSyOaLeaveApprovalByIds(Long[] ids)
    {
        return syOaLeaveApprovalMapper.deleteSyOaLeaveApprovalByIds(ids);
    }

    /**
     * 删除请假审批信息
     * 
     * @param id 请假审批主键
     * @return 结果
     */
    @Override
    public int deleteSyOaLeaveApprovalById(Long id)
    {
        return syOaLeaveApprovalMapper.deleteSyOaLeaveApprovalById(id);
    }

    /**
     * 提交申请
     * @param syOaLeaveApproval
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void submitApply(SyOaLeaveApproval syOaLeaveApproval) throws Exception {
        // 初始化值
        Map<String, Object> variables = createVariables(syOaLeaveApproval);
        // 启动流程
        processService.submitApply(syOaLeaveApproval, "oaLeave", variables);
        // 添加抄送人
        syOaCopyService.addCopyUsers("QJSP", syOaLeaveApproval.getId());
        //新增审批记录
        List<Long> longs = addApprovalRecord(syOaLeaveApproval, variables);
        // 通知审批人
        sendApproveMessage(longs);
        syOaLeaveApproval.setBusinessStatus(Constants.APPROVE);
        updateSyOaLeaveApproval(syOaLeaveApproval);
    }

    /**
     * 新增审批记录
     * @param syOaLeaveApproval
     * @param map
     * @return
     */
    private List<Long> addApprovalRecord(SyOaLeaveApproval syOaLeaveApproval, Map<String, Object> map) {
        List<Long> list = new ArrayList<>();
        int sequence = 1;
        //  发起人
        ApprovalRecord firstApprovalRecord = getApprovalRecord(syOaLeaveApproval);
        firstApprovalRecord.setSequence(sequence);
        firstApprovalRecord.setApprovalStatus(Constants.COMPLETED);
        firstApprovalRecord.setTypeOperation(Constants.AGREE);
        firstApprovalRecord.setBusinessStatus(Constants.APPROVE);
        firstApprovalRecord.setApproverId(Long.valueOf(syOaLeaveApproval.getApplyUserId()));
        firstApprovalRecord.setApproverName(syOaLeaveApproval.getApplyUserName());
        approvalRecordMapper.insertApprovalRecord(firstApprovalRecord);

        //是否直接主管
        if ((boolean)map.get("isDirectManager")){
            sequence++;
            //  第二审批人
            ApprovalRecord secondApprovalRecord = getApprovalRecord(syOaLeaveApproval);
            secondApprovalRecord.setSequence(sequence);
            secondApprovalRecord.setApprovalStatus(Constants.APPROVE);
            secondApprovalRecord.setApproverId((Long) map.get("bigLeaderId"));
            secondApprovalRecord.setApproverName((String) map.get("bigLeader"));
            approvalRecordMapper.insertApprovalRecord(secondApprovalRecord);
            list.add((Long) map.get("bigLeaderId"));
        }else{
            sequence++;
            //  第二审批人
            ApprovalRecord secondApprovalRecord = getApprovalRecord(syOaLeaveApproval);
            secondApprovalRecord.setSequence(sequence);
            secondApprovalRecord.setApprovalStatus(Constants.APPROVE);
            secondApprovalRecord.setApproverId((Long) map.get("leaderId"));
            secondApprovalRecord.setApproverName((String) map.get("leader"));
            approvalRecordMapper.insertApprovalRecord(secondApprovalRecord);
            list.add((Long) map.get("leaderId"));
            if ((boolean) map.get("isGreaterThan")) {
                //假期大于3天
                sequence++;
                //  第二审批人
                ApprovalRecord approvalRecord = getApprovalRecord(syOaLeaveApproval);
                approvalRecord.setSequence(sequence);
                approvalRecord.setApprovalStatus(Constants.APPROVE);
                approvalRecord.setApproverId((Long) map.get("ceoId"));
                approvalRecord.setApproverName((String) map.get("ceo"));
                approvalRecordMapper.insertApprovalRecord(approvalRecord);
            }
        }
        return list;
    }

    /**
     * 获取审批记录对象
     *
     * @param approval
     * @return
     */
    private ApprovalRecord getApprovalRecord(SyOaLeaveApproval approval) {
        ApprovalRecord approvalRecord = new ApprovalRecord();
        approvalRecord.setSerialNum(approval.getSerialNum());
        approvalRecord.setUserId(Long.valueOf(approval.getApplyUserId()));
        approvalRecord.setOrderId(approval.getId());
        approvalRecord.setUserName(approval.getApplyUserName());
        approvalRecord.setUpdateTime(DateUtils.parseDate(DateUtils.getTime()));
        approvalRecord.setUpdateBy(approval.getApplyUserName());
        approvalRecord.setCreateBy(approval.getApplyUserName());
        approvalRecord.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
        return approvalRecord;
    }


    /**
     * 初始化值
     * @param syOaLeaveApproval
     * @return
     */
    private Map<String, Object> createVariables(SyOaLeaveApproval syOaLeaveApproval) {
        Map<String, Object> var = new HashMap<>(500);
        // 判断申请人是否是主管
        List<SysUserRoleDeptInfo> userList = sysUserService.selectUsersByUserName(syOaLeaveApproval.getApplyUserName());
        if (CollectionUtils.isEmpty(userList)) {
            throw new BaseException("外出审批-判断是否为直接主管集合为空");
        }
        List<SysUserRoleDeptInfo> collect = userList.stream().filter(a -> "直接主管".equals(a.getRoleName())).collect(Collectors.toList());
        var.put("isDirectManager", collect.size() > 0);
        SyOaCopyConfig syOaCopyConfig = new SyOaCopyConfig();
        syOaCopyConfig.setNumber("QJSP_LEADER");
        List<SyOaCopyConfig> syOaCopyConfigs = syOaCopyConfigMapper.selectSyOaCopyConfigList(syOaCopyConfig);
        if (collect.size() > 0) {
            // 申请人是直接主管,由余总审批
            if (CollectionUtils.isEmpty(syOaCopyConfigs)) {
                throw new BaseException("createVariables", "请假审批获取领导负责人失败");
            }
            var.put("bigLeader", syOaCopyConfigs.get(0).getCopyUserName());
            var.put("bigLeaderId",syOaCopyConfigs.get(0).getCopyUserId());
        } else {
            var.put("isGreaterThan", false);
            //休假时长小于3天，直接主管审批
            var.put("leader", userList.get(0).getLeader());
            var.put("leaderId",userList.get(0).getLeaderId());

            if (syOaLeaveApproval.getLeaveDuration() >= 24L){
                var.put("isGreaterThan", true);
                //休假时长大于3天，余晗审批
                var.put("ceo", syOaCopyConfigs.get(0).getCopyUserName());
                var.put("ceoId",syOaCopyConfigs.get(0).getCopyUserId());
            }
        }
        return var;
    }

    /**
     * 给审批人推送消息
     * @param addJpushList
     */
    private void sendApproveMessage(List<Long> addJpushList) {
        try {
            List<String> addRegIds = jpushMapper.selectRegistrationIdsByUserIds(addJpushList);
            if (!CollectionUtils.isEmpty(addRegIds)){
                UniJpushUtils.sendApproveMessage(addRegIds);
            }
        } catch (Exception e) {
            LOGGER.error("请假审批审批人推送通知失败",e);
        }
    }
}
